package edu.gatech.bsbmule.presenter;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;

import javax.swing.JLabel;

import edu.gatech.bsbmule.model.Game;
import edu.gatech.bsbmule.model.LandOffice;
import edu.gatech.bsbmule.model.Map;
import edu.gatech.bsbmule.model.Player;
import edu.gatech.bsbmule.model.Tile;
import edu.gatech.bsbmule.view.IMapScreen;
import edu.gatech.bsbmule.view.TownWindow;

/**
 * Presenter for map screen, player status panel and status bar
 * 
 * @author BSB
 * @version 1.0 10/26/2013
 */
public class MapScreenPresenter {
	
	private IMapScreen view;
		
	public MapScreenPresenter(IMapScreen view) {
		this.view = view;
	}
	
	/**
	 * Display tiles on the map screen
	 * 
	 * @param modelMap map model
	 */
	public void displayTiles(Map modelMap) {
		view.displayTiles(modelMap.getTiles());
		updateAllJLabelColors();
	}
	
	/**
	 * Setup listener of what happens if user clicks on a tile
	 * 
	 * @param map
	 */
	public void setTileButtonListener(final Map map) {
		view.setTileListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				// Get source of the click and the correspondent tile
				JLabel labelClicked = (JLabel) e.getSource();
				Point location = view.queryLocationByJLabel(labelClicked);
				Tile tile = map.getTile((int) location.getX(), (int) location.getY());
				Player currentPlayer = Game.getInstance().getCurrentPlayer(); 
				
				// If town is clicked
				if (tile.getTerrain() == Tile.TERRAIN_TOWN) {
					
					// If already in Land Office, exit Land office
					if (view.getIntrade()) {
						setIntrade(false);
						setTradingStatus(false);
					}
					
					// Else display the TownWindow
					else
					{
						TownWindow.getInstance().setVisible(true);
					}
				}
				
				// If already in land office
				if (view.getIntrade())
				{	
					LandOffice landOffice = new LandOffice();
					
					// If the tile is available, sell/grant the tile
					if (landOffice.sellTile(currentPlayer, tile)) {
						view.updateJLabelColor(location, currentPlayer.getColor());
						view.updatePlayerInfo(currentPlayer);
					}
					
					// Else it is not available
					else
					{
						System.out.println("Your selection is not valid!");
					}
				}
				
				// @greg javadoc this
				if (view.hasMule(currentPlayer)){
					// If the tile is available
					if (currentPlayer.ownsTile(tile)){
						tile.addMule(currentPlayer.getMule());
						System.out.println("Mule used");
					}
					else
						System.out.println("You don't own that. You wasted your mule.");
					currentPlayer.setMule(-1);
				}
				
				// Not in land office and not able to click a tile
				else
				{
					System.out.println("Not in the land office!");
				}
			}
		});
	}
	
	/**
	 * Update all tiles' colors by their owners
	 */
	private void updateAllJLabelColors() {
		List<Player> players = Game.getInstance().getPlayers();
		for (Player p : players) {
			for (Tile t : p.getTiles()) {
				view.updateJLabelColor(t.getLocation(), p.getColor());
			}
		}
	}
	
	/**
	 * Update right player panel information
	 * 
	 * @param player
	 */
	public void updatePlayerInfo(Player player) {
		view.updatePlayerInfo(player);
	}
	
	/**
	 * Set whether the map is in trade or not
	 * 
	 * @param inTrade whether in land office
	 */
	public void setIntrade(boolean inTrade) {
		view.setIntrade(inTrade);
	}
	
	/**
	 * @greg javadoc this
	 * 
	 * @param mule
	 */
	public void setWithMule(boolean mule){
		view.setWithMule(mule);
	}
	
	/**
	 * Set status bar label of current turn number
	 * 
	 * @param turn turn number
	 */
	public void setTurnStatus(int turn) {
		view.setTurnStatus(Integer.toString(turn));
	}
	
	/**
	 * Set status bar label of Land Office or not
	 * 
	 * @param turn turn number
	 */
	public void setTradingStatus(boolean trading) {
		if (trading)
			view.setTradingStatus("YES");
		else
			view.setTradingStatus("NO");
	}
	
	/**
	 * Set status bar label of FreeProperty phase or not
	 * 
	 * @param free land grant phase or not
	 */
	public void setFreePropertyStatus(boolean free) {
		if (free)
			view.setFreePropertyStatus("YES");
		else
			view.setFreePropertyStatus("NO");
	}
	
	/**
	 * Log a string into the log window
	 */
	public void log(String s) {
		view.appendLog(s);
	}
	
	/**
	 * Start one-second interval timer for updating remaining time constantly
	 */
	public void startOneSecTimer() {
		view.startOneSecTimer();
	}
	
	/**
	 * Stop the timer above
	 */
	public void stopOneSecTimer() {
		view.stopOneSecTimer();
	}
}
